
#Memory is conserved by using a generator expression instead: 
ord = (x*x for x in range(10))

gen = iter(ord) # Po wywołaniu metody iter obiektu iterowalnego
                # metoda ta zwraca iterator - obiekt implementujący
                # metodę __next__() - MOZE to być ten sam obiekt!

print gen.next()
print gen.next()
print gen.next()
print gen.next()

for i in ord:
    print i
    
squeares = (x ** 2 for x in range(5))

#generator implementuje next()
print type(squeares)

print squeares.next()
print squeares.next()
print squeares.next()
print squeares.next()

print squeares is iter(squeares)

print iter(squeares)
print iter(squeares)

def fun(x):
    return x

sq = (fun(x) for x in range(4))

print type(sq)

print sq.next()
print sq.next()
print sq.next()
print sq.next()







